import {Injectable} from '@angular/core';
import {Observable, Subject} from 'rxjs';
import {TagData} from '../../entity/tag-data.model';
import {DatePipe} from '@angular/common';
import {AppConfig} from '../../config';
import {FaultData} from './fault-data';
import {InterceptorService} from '../interceptor/interceptor-service';

@Injectable()
export class HistoryService {
  /**
   * 时间格式化字符串
   *
   * @private
   * @type {string}
   * @memberof HistoryService
   */
  private fomat: string = 'yyyy-MM-dd HH:mm:ss';
  private readonly param = 'historys';

  private get url(): string {
    return `${AppConfig.APP_RESTFUL}/${this.param}`;
  }

  private timers: any[] = [];
  /**
   * 主题对象数组
   *
   * @private
   * @type {Subject<any>[]}
   * @memberof IMPushService
   */
  private subjectMap: Subject<any>[] = [];

  constructor(
    private http: InterceptorService,
    // private http: Http,
    private datePipe: DatePipe,
  ) {
  }

  /**
   * 获得测点快照值
   *
   * @param {string[]} codes
   * @returns {(Promise<TagData[]>)}
   * @memberof HistoryService
   */
  public getSnapshots(codes: string[]): Promise<TagData[]> {
    return this.http.post(`${this.url}/snapshots`, JSON.stringify(codes))
      .toPromise()
      .then(response => {
        try {
          let result = response;
          switch (result.code) {
            case '200':
              return result.data;
            case '-1':
              throw new Error(result.message);
          }
        }
        catch (error) {
          throw error;
        }
      })
      .catch(this.handleError);
  }


  /**
   * 定时查询测点历史值
   *
   * @param {number} timerInterval
   * @param {string[]} codes
   * @param {Date} time
   * @returns {Subject<TagData[]>}
   * @memberof HistoryService
   */
  public getHistoriesWithTimer(timerInterval: number, codes: string[], time: Date): Subject<TagData[]>;
  public getHistoriesWithTimer(timerInterval: number, codes: string[], start: Date, end: Date): Subject<TagData[]>;
  public getHistoriesWithTimer(timerInterval: number, codes: string[], start: Date, end: Date, interval: number): Subject<TagData[]>;
  public getHistoriesWithTimer(timerInterval: number, codes: string[], start: Date, end?: Date, interval?: number): Subject<TagData[]> {
    let subject = new Subject<TagData[]>();
    this.subjectMap.push(subject);
    this.getHistories(codes, start, end, interval).then(res => {
      subject.next(res);
      // 开启定时器
      let timer = setInterval(() => {
        this.getHistories(codes, start, end, interval).then(timerRes => {
          subject.next(timerRes);
        }).catch(timerError => {
          subject.error(timerError);
        });
      }, timerInterval * 1000);
      this.timers.push(timer);
    }).catch(error => {
      subject.error(error);
    });
    return subject;
  }

  /**
   * 根据时间点获得历史数据
   *
   * @param {string[]} codes 测点编码集合
   * @param {Date} time 时间点
   * @returns {(Promise<TagData[]>)}
   * @memberof HistoryService
   */
  public getHistories(codes: string[], time: Date): Promise<TagData[]>;
  /**
   * 根据时间范围获得历史数据
   *
   * @param {string[]} codes 测点编码集合
   * @param {Date} start 开始时间
   * @param {Date} end 结束时间
   * @returns {(Promise<TagData[]>)}
   * @memberof HistoryService
   */
  public getHistories(codes: string[], start: Date, end: Date): Promise<TagData[]>;
  /**
   *  根据时间范围和时间间隔获得历史数据
   *
   * @param {string[]} codes 测点编码集合
   * @param {Date} start 开始时间
   * @param {Date} end 结束时间
   * @param {number} interval 时间间隔
   * @returns {(Promise<TagData[]>)}
   * @memberof HistoryService
   */
  public getHistories(codes: string[], start: Date, end: Date, interval: number): Promise<TagData[]>;
  /**
   *
   *
   * @param {*} codes
   * @param {*} start
   * @param {*} [end]
   * @param {*} [interval]
   * @returns {Promise<TagData[]>}
   * @memberof HistoryService
   */
  public getHistories(codes: any, start: any, end?: any, interval?: any): Promise<TagData[]> {
    let resqustUrl = this.url;
    let startFomat: string = '';
    let endFomat: string = '';
    if (interval != null) {
      if (start == null)
        return Promise.reject('开始时间不能为空！');
      if (end == null)
        return Promise.reject('结束时间不能为空！');
      if (start >= end)
        return Promise.reject('开始时间应该小于结束时间！');
      if (!(interval && interval >= 1))
        return Promise.reject('时间间隔不能为空，并且应该大于等于1秒');
      startFomat = this.datePipe.transform(start, this.fomat);
      endFomat = this.datePipe.transform(end, this.fomat);
      resqustUrl = `${resqustUrl}/startTime/${startFomat}/endTime/${endFomat}/interval/${interval}`
    } else if (end != null) {
      if (start == null)
        return Promise.reject('开始时间不能为空！');
      if (end == null)
        return Promise.reject('结束时间不能为空！');
      if (start >= end)
        return Promise.reject('开始时间应该小于结束时间！');

      startFomat = this.datePipe.transform(start, this.fomat);
      endFomat = this.datePipe.transform(end, this.fomat);
      resqustUrl = `${resqustUrl}/startTime/${startFomat}/endTime/${endFomat}`;
    } else {
      if (start == null)
        return Promise.reject('时间点不能为空！');
      startFomat = this.datePipe.transform(start, this.fomat);
      //resqustUrl = `http://192.168.15.150:8585/webapi/v1/historys/time/${startFomat}`;
      resqustUrl = `${resqustUrl}/time/${startFomat}`;
    }
    return this.http.post(resqustUrl, JSON.stringify(codes))
      .toPromise()
      .then(response => {
        try {
          let result = response;
          switch (result.code) {
            case '200':
              return result.data as TagData[];
            case '-1':
              throw new Error(result.message);
          }
        }
        catch (error) {
          throw error;
        }
      })
      .catch(this.handleError);
  }

  /**
   * 获得统计值
   *
   * @param {string[]} codes
   * @param {Date} start
   * @param {Date} end
   * @returns {(Promise<any> | Observable<any>)}
   * @memberof HistoryService
   */
  public getSummaries(codes: string[], start: Date, end: Date): Promise<Summary[]>;
  public getSummaries(codes: string[], start: Date, end: Date, interval: number): Promise<Summary[]>;
  public getSummaries(codes: string[], start: Date, end: Date, expr: string): Promise<Summary[]>;
  public getSummaries(codes: any, start: any, end: any, expr?: any): Promise<Summary[]> {
    throw new Error('Method not implemented.');

  }


  /**
   * 根据风机Id，获得时间范围内的该台风机故障信息
   *
   * @param {number} turbineId
   * @param {string} alarmCategory
   * @param {Date} start
   * @param {Date} end
   * @param {{ pageIndex: number; eachPage: number; }} [page]
   * @returns {Promise<FaultPage>}
   * @memberof HistoryService
   */


  public getTurbineFaults(turbineIds: number[], start: Date, end: Date, alarmCategoryIds?: number[], page?: { pageIndex: number; eachPage: number; }): Promise<FaultData[]> {

    // let resqustUrl = `http://192.168.15.150:8585/webapi/v1/historyAlarms`;
    let resqustUrl = `${AppConfig.APP_RESTFUL}/historyAlarms`;
    let startFomat: string = '';
    let endFomat: string = '';

    if (turbineIds == null)
      return Promise.reject('请选择设备！');
    if (start == null)
      return Promise.reject('开始时间不能为空！');
    if (end == null)
      return Promise.reject('结束时间不能为空！');
    if (start >= end)
      return Promise.reject('开始时间应该小于结束时间！');

    startFomat = this.datePipe.transform(start, this.fomat);
    endFomat = this.datePipe.transform(end, this.fomat);
    resqustUrl = `${resqustUrl}/startTime/${startFomat}/endTime/${endFomat}`;

    return this.http.post(resqustUrl, JSON.stringify(turbineIds))
      .toPromise()
      .then(response => {
        try {
          let result = response;
          switch (result.code) {
            case '200':
              return result.data as FaultData[];
            case '-1':
              throw new Error(result.message);
          }
        }
        catch (error) {
          throw error;
        }
      })
      .catch(this.handleError);
  }

  public getInverterFaults(deviceIds: number[], start: Date, end: Date, alarmCategoryIds?: number[], page?: { pageIndex: number; eachPage: number; }): Promise<FaultData[]> {

    let resqustUrl = `${AppConfig.APP_RESTFUL}/historyAlarms`;
    let startFomat: string = '';
    let endFomat: string = '';

    if (deviceIds == null)
      return Promise.reject('请选择逆变器！');
    if (start == null)
      return Promise.reject('开始时间不能为空！');
    if (end == null)
      return Promise.reject('结束时间不能为空！');
    if (start >= end)
      return Promise.reject('开始时间应该小于结束时间！');

    startFomat = this.datePipe.transform(start, this.fomat);
    endFomat = this.datePipe.transform(end, this.fomat);
    resqustUrl = `${resqustUrl}/device/startTime/${startFomat}/endTime/${endFomat}`;

    return this.http.post(resqustUrl, JSON.stringify(deviceIds))
      .toPromise()
      .then(response => {
        try {
          let result = response;
          switch (result.code) {
            case '200':
              return result.data as FaultData[];
            case '-1':
              throw new Error(result.message);
          }
        }
        catch (error) {
          throw error;
        }
      })
      .catch(this.handleError);
  }

  public dispose() {
    this.timers.forEach(timer => {
      clearInterval(timer);
    });
    this.subjectMap.forEach(subject => {
      subject.unsubscribe();
    })
  }

  public getDeviceStatuses(codes: any[], startTime: Date, endTime: Date): Promise<TagData[]> {
    let startFomat = this.datePipe.transform(startTime, this.fomat),
      endFomat = this.datePipe.transform(endTime, this.fomat);
    let resqustUrl = `${this.url}/DistinctHistoryData/startTime/${startFomat}/endTime/${endFomat}`;
    //let resqustUrl = `http://192.168.15.110:8989/webapi/v1/historys/DistinctHistoryData/startTime/${startFomat}/endTime/${endFomat}`;

    return this.http.post(resqustUrl, JSON.stringify(codes))
      .toPromise()
      .then(response => {
        try {
          let result = response;
          switch (result.code) {
            case '200':
              return result.data as TagData[];
            case '-1':
              throw new Error(result.message);
          }
        }
        catch (error) {
          throw error;
        }
      })
      .catch(this.handleError);
  }

  private handleError(error: any): Promise<any> {
    return Promise.reject(error.message || error);
  }
}

/**
 * 风机故障信息页
 *
 * @export
 * @interface FaultPage
 */
export interface FaultPage {
  faults: FaultData[];
  page: Page;
}


/**
 * 分页信息
 *
 * @export
 * @interface Page
 */
export interface Page {
  index: number;
  totle: number;
  each: number;
}

/**
 * 测点统计信息
 *
 * @export
 * @interface Summary
 */
export interface Summary {
  /**
   * 合计值
   *
   * @type {number}
   * @memberof Summary
   */
  total: number;
  /**
   * 平均值
   *
   * @type {number}
   * @memberof Summary
   */
  avg: number;
  /**
   * 最大值
   *
   * @type null
   * @memberof Summary
   */
  max: number;
  /**
   * 最小值
   *
   * @type {number}
   * @memberof Summary
   */
  min: number;
  /**
   * 有效值个数
   *
   * @memberof Summary
   */
  effective: number;
  /**
   * 加权平均值
   *
   * @memberof Summary
   */
  powerAvg: number;
  /**
   * 批次
   *
   * @type {number}
   * @memberof Summary
   */
  index: number;
  /**
   * 查询的开始时间
   *
   * @type {Date}
   * @memberof Summary
   */
  start: Date;
  /**
   * 查询的结束时间
   *
   * @type {Date}
   * @memberof Summary
   */
  end: Date;
  /**
   * 最大值的时间
   *
   * @type {Date}
   * @memberof Summary
   */
  maxDate: Date;
  /**
   * 最小值的时间
   *
   * @type {Date}
   * @memberof Summary
   */
  minDate: Date;
}


// WEBPACK FOOTER //
// ./src/app/service/data-source/history.service.ts
